﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.ComponentModel;
using HaiHui.Data;

namespace HaiHui.Business
{
    /// <summary>
    /// Reprezinta entitatea "Album"
    /// </summary>
    public class Album
    {

        private PhotoCollection m_AlbumPhotos;
        public PhotoCollection AlbumPhotos
        {
            get { return m_AlbumPhotos; }
        }

        /// <summary>
        /// se seteaza flag "true" doar dupe ce s-au incarcat tati pozili.
        /// todo: creca ar trebui sa folosesc un lock.
        /// </summary>
        public bool PicturesLoaded { get; set; }

        public int Id { get; set; }
        public string Name { get; set; }
        public string PicsUrl { get; set; }
        public string DetailsUrl { get; set; }

        public string Descriere { get; set; }
        public string CuvinteCheie { get; set; }
        public string Tara { get; set; }
        public string Localitate { get; set; }
        public bool AcceptaComentarii { get; set; }
        public bool Public { get; set; }

        /// <summary>
        /// folosit pentru niste copilaresti incercari de sincronizare a unor threaduri
        /// </summary>
        private object Locker = new object();

        /// <summary>
        /// Cum ii zice, aia face.
        /// </summary>
        internal void GetDetailsData()
        {
            lock (Locker)
            {
                string detailsHtmlOriginal = HttpUtils.Get(DetailsUrl);
                string detailsHtml = detailsHtmlOriginal;

                int index;
                int length;
                string startPattern;
                string endPattern;

                #region DESCRIERE
                startPattern = "<textarea name=\"descriere\">";
                endPattern = "</textarea>";
                Descriere = Utils.ScrapeNext(ref detailsHtml, startPattern, endPattern);
                #endregion

                Id = Int32.Parse(DetailsUrl.Substring(DetailsUrl.IndexOf("id=") + 3));

                #region CUVINTE CHEIE
                startPattern = "name=\"tags\" value=\"";
                endPattern = "\" /><br />";
                CuvinteCheie = Utils.ScrapeNext(ref detailsHtml, startPattern, endPattern);
                #endregion

                #region TARA
                startPattern = "selected='selected' >";
                endPattern = "</option>";
                Tara = Utils.ScrapeNext(ref detailsHtml, startPattern, endPattern);
                #endregion

                Localitate = Utils.ScrapeNext(ref detailsHtml, startPattern, endPattern);

                if (detailsHtml.Contains("name=\"accept_comentarii\" value=\"1\" checked='checked'"))
                {
                    AcceptaComentarii = true;
                }

                if (detailsHtml.Contains("name=\"activ\" value=\"1\" checked='checked'"))
                {
                    Public = true;
                }
            }
        }

        /// <summary>
        /// Incarca pozele albumului
        /// </summary>
        internal void GetPictures()
        {
            string picListHtml = HttpUtils.Get(PicsUrl);

            List<Picture> pics = new List<Picture>();

            int index = -1;
            int length;

            string startPattern;
            string endPattern;
            string largePictureHtmlUrl;
            string lasgePictureHtml;
            string largePictureUrl;
            string smallPictureUrl;

            do
            {
                //Deci aici facem chestia aia rusinoasa in care parsam ca babele html-ul. 
                //Daca as sti expresii... regulate, le-as folosi. 

                index = picListHtml.IndexOf("foto/");
                if (index > -1)
                {
                    Picture pic = new Picture();
                    picListHtml = picListHtml.Substring(index);
                    length = picListHtml.IndexOf("\" title=\"");

                    largePictureHtmlUrl = picListHtml.Substring(0, length);
                    largePictureHtmlUrl = String.Concat(Constants.BaseURL, largePictureHtmlUrl);
                    lasgePictureHtml = HttpUtils.Get(largePictureHtmlUrl);

                    startPattern = ";\"><img src=\"";
                    endPattern = "\" class=\"details_image_center";
                    largePictureUrl = Utils.ScrapeNext(ref lasgePictureHtml, startPattern, endPattern); ;


                    startPattern = "<img src=\"";
                    endPattern = "\"";
                    smallPictureUrl = Utils.ScrapeNext(ref picListHtml, startPattern, endPattern);

                    pic.Album = this;
                    pic.SmallImageUrl = smallPictureUrl;
                    pic.LargeImageUrl = largePictureUrl;

                    pic.Id = Int32.Parse(largePictureHtmlUrl.Substring(largePictureHtmlUrl.LastIndexOf("_") + 1).Replace(".html", ""));

                    pic.GetDetailsData();

                    //Lansam asta pe alt thread ca sa "optimizam" oleaca pornitul greoi.
                    //Sta mult pentru ca pentru fiecare object Picture descarca 2 poze, poza mare si OF COURSE poza mica.
                    Thread t = new Thread(new ThreadStart(pic.GetImages));
                    t.Start();
                    
                    pics.Add(pic);
                }

            } while (index != -1);

            //gata, am incarcat pozele
            this.m_AlbumPhotos = new PhotoCollection(pics);
        }


        /// <summary>
        /// 
        /// In zona ce urmeaza avem urmatoarele: 
        /// 
        /// un delegat pt apelu asincron de "incarcaPoze()"
        /// 
        /// un callback care "se trage" :| cand e gata incarcatul.
        /// In asta se seteaza si marele flag.
        /// 
        /// </summary>
        /// 

        #region Getting the pictures asynchronously
        delegate void GetPicturesDelegate();
        internal void GetPicturesAsync()
        {
            GetPicturesDelegate dlg = new GetPicturesDelegate(GetPictures);
            dlg.BeginInvoke(new AsyncCallback(GetPicturesCallback), dlg);

        }
        internal void GetPicturesCallback(IAsyncResult result)
        {
            GetPicturesDelegate dlg = (GetPicturesDelegate)result.AsyncState;
            PicturesLoaded = true;

            dlg.EndInvoke(result);
        } 
        #endregion
    }
}
